#include "DynamicArray.h"

DynamicArray *newDynamicArray()
{
    DynamicArray *res = (DynamicArray *)malloc(sizeof(DynamicArray));
    res->size = 0;
    res->capacity = DEFAULT_SIZE;
    res->datas = (DataType *)malloc(sizeof(DataType) * DEFAULT_SIZE);
    return res;
}

DynamicArray *newDynamicArray(int size)
{
    DynamicArray *res = (DynamicArray *)malloc(sizeof(DynamicArray));
    res->size = 0;
    res->capacity = size;
    res->datas = (DataType *)malloc(sizeof(DataType) * size);
    return res;
}

DynamicArray *newDynamicArray(DataType *datas, int size)
{
    DynamicArray *res = (DynamicArray *)malloc(sizeof(DynamicArray));
    res->size = size;
    res->capacity = size > DEFAULT_SIZE ? size : DEFAULT_SIZE;
    res->datas = (DataType *)malloc(sizeof(DataType) * (res->capacity));
    for (int i = 0; i < size; i++)
    {
        (res->datas)[i] = datas[i];
    }
    return res;
}

void printDynamicArray(DynamicArray *da)
{
    printf("info: The DynamicArray %p ", &da);
    printf("{size: %d ,capacity: %d ,datas:[", da->size, da->capacity);
    for (int i = 0; i < da->size - 1; i++)
    {
        printf("%d, ", da->datas[i]);
    }
    if (da->size != 0)
    {
        printf("%d", da->datas[da->size - 1]);
    }
    printf("]}\n");
}

void insert(DynamicArray *da, int index, DataType val)
{
    if (index < 0 || index > da->size)
    {
        myErrorLog();
        printf("insert index %d out of range! the size of datas is %d\n", index, da->size);
        assertFalse(index < 0 || index > da->size);
        return;
    }

    if (da->size == da->capacity)
    {
        da->capacity *= 2;
        DataType *newDatas = (DataType *)malloc(sizeof(DataType) * da->capacity);
        for (int i = 0; i < index; i++)
        {
            newDatas[i] = da->datas[i];
        }
        newDatas[index] = val;
        for (int i = index + 1; i <= da->size; i++)
        {
            newDatas[i] = da->datas[i - 1];
        }
        free(da->datas);
        da->datas = newDatas;
    }
    else
    {
        for (int i = da->size; i > index; i--)
        {
            da->datas[i] = da->datas[i - 1];
        }
        da->datas[index] = val;
    }
    da->size++;
}

void remove(DynamicArray *da, int index)
{
    if (index < 0 || index >= da->size)
    {
        myErrorLog();
        printf("remove index %d out of range! the size of datas is %d\n", index, da->size);
        assertFalse(index < 0 || index >= da->size);
        return;
    }

    for (int i = index; i < da->size - 1; i++)
    {
        da->datas[i] = da->datas[i + 1];
    }
    da->size--;
}

void update(DynamicArray *da, int index, DataType newVal)
{
    if (index < 0 || index >= da->size)
    {
        myErrorLog();
        printf("update index %d out of range! the size of datas is %d\n", index, da->size);
        assertFalse(index < 0 || index >= da->size);
        return;
    }
    da->datas[index] = newVal;
}

int find(DynamicArray *da, DataType val)
{
    for (int i = 0; i < da->size; i++)
    {
        if (da->datas[i] == val)
        {
            return i;
        }
    }
    return -1;
}

void destroy(DynamicArray *da)
{
    free(da->datas);
    free(da);
    myInfoLog("destroy DynamicArray");
}